﻿using Abp.Domain.Services;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using Abp.UI;
using AVIS.OutBound.AWD;
using AVIS.OutBound.Cities;
using AVIS.OutBound.Contents;
using AVIS.OutBound.Countrys;
using AVIS.OutBound.ORFleets;
using AVIS.OutBound.Regions;
using AVIS.OutBound.Stores;
using AVIS.OutBound.Wizard;
using AVIS.OutBound.WizardAgent;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVIS.OutBound.CarGroups
{
    public class CarGroupManager : DomainService, ICarGroupManager
    {
        #region 构造函数
        private readonly WizardVehAvailRateAgent _wizardVehAgent;
        private readonly WizardVehRateRuleAgent _wizardRateAgent;
        private readonly ICacheManager _cacheManager;
        private readonly IObjectMapper _objectMapper;
        private readonly IORFleetManager _fleetManager;
        private readonly ICityManager _cityManager;
        private readonly IStoreManager _storeManager;
        private readonly IRegionManager _regionManager;
        private readonly ICountryManager _countryManager;
        private readonly IContentManager _contentManager;
        private readonly IAWDManager _awdManager;
        private readonly IWizardManager _wizardManager;

        public CarGroupManager(ICacheManager cacheManager,
            IObjectMapper objectMapper,
            IORFleetManager fleetManager,
            ICityManager cityManager,
            IStoreManager storeManager,
            IRegionManager regionManager,
            IAWDManager awdManager,
            IWizardManager wizardManager,
            ICountryManager countryManager,
            IContentManager contentManager)
        {
            _wizardVehAgent = new WizardVehAvailRateAgent();
            _wizardRateAgent = new WizardVehRateRuleAgent();
            _cacheManager = cacheManager;
            _objectMapper = objectMapper;
            _fleetManager = fleetManager;
            _cityManager = cityManager;
            _storeManager = storeManager;
            _regionManager = regionManager;
            _awdManager = awdManager;
            _wizardManager = wizardManager;
            _countryManager = countryManager;
            _contentManager = contentManager;
        }

        #endregion

        /// <summary>
        /// 获取指定套餐的车组
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public List<CarGroup> GetCarGroups(AgentCarGroupsRequest request)
        {
            var listCarGroup = new List<CarGroup>();
            var store = _storeManager.GetStoreByCode(request.PickUpStoreCode);

            // 从Wizard接口中获取车组信息
            var rs = _objectMapper.Map<CarGroupsRequest>(request);
            rs.AWD = _awdManager.GetRealAWDCode(rs.AWD); // 获取真实的AWD号，一般国内的AWD号是以CN开头的
            var response = _wizardVehAgent.GetCarGroups(rs);
            _wizardManager.HandleErrorMessage(response); // 处理Wizard结果的错误信息

            // 处理车组的排序号（在推荐列表的车组排在最前面）
            var sortList = GetCarGroupSortList(request.PickUpStoreCode);
            foreach (var dto in response.Data)
            {
                // 构建车组信息
                var carGroup = BuildCarGroup(dto, store, true);
                carGroup.SeqNo = sortList.IndexOf(carGroup.ModelCode);        // 设置排序号
                carGroup.IsRecommend = carGroup.SeqNo >= 0 ? true : false;    // 只有推荐车组的排序号才会大于零
                listCarGroup.Add(carGroup);
            };

            // 按 SeqNo（倒序） 和 ModelName（正序） 排序后返回
            return listCarGroup.OrderByDescending(c => c.SeqNo).ThenBy(c => c.ModelName).ToList();
        }

        /// <summary>
        /// 获取指定SIPPCode和RateCode的单个车组信息（包含增值服务）
        /// </summary>
        /// <returns>单个车组信息</returns>
        public CarGroup GetCarGroup(AgentCarEquipmentRequest request)
        {
            var store = _storeManager.GetStoreByCode(request.PickUpStoreCode);

            // 从Wizard接口中获取车组信息
            var rs = _objectMapper.Map<CarEquipmentRequest>(request);
            rs.AWD = _awdManager.GetRealAWDCode(rs.AWD); // 获取真实的AWD号，一般国内的AWD号是以CN开头的
            var response = _wizardRateAgent.GetCarGroupWithEquipments(rs);
            _wizardManager.HandleErrorMessage(response); // 处理Wizard结果的错误信息

            // 构建车组信息
            var carGroup = BuildCarGroup(response.Data, store);
            return carGroup;
        }

        /// <summary>
        /// 构建车组信息（结合本地数据库和Wizard接口的车组信息）
        /// </summary>
        /// <param name="dto">Wizard返回的车组信息</param>
        /// <param name="pickUpStore">取车门店</param>
        /// <param name="isSimple">是否采用简要数据信息</param>
        /// <returns></returns>
        public CarGroup BuildCarGroup(CarGroupDto dto, Store pickUpStore, bool isSimple = false)
        {
            var carGroup = _objectMapper.Map<CarGroup>(dto);

            // 1. 读取数据库的车辆信息来更新车辆信息
            SetFleetInfo(carGroup, pickUpStore.RegionCode);

            // 2. 设置车组增值服务的中文名称，如果没有对应的中文名称，则排除之。
            SetCarEquipments(carGroup);

            if (isSimple)
            {
                // 3.1 套餐价格包含的简要内容（如：碰撞险，盗抢险，第三者责任险）
                carGroup.PriceInclue.SimpleContents = GetSimplePriceInclude(carGroup);
            }
            else
            {
                // 3.2 套餐价格包含的中文详细内容（行驶限制、保险项目、费用）
                carGroup.PriceInclue.Contents = GetPriceInclude(carGroup);
            }

            return carGroup;
        }

        #region 私有方法
        /// <summary>
        /// 获取指定门店的车组排序列表
        /// </summary>
        /// <param name="storeCode">取车门店Code</param>
        /// <returns></returns>
        private List<string> GetCarGroupSortList(string storeCode)
        {
            var recommendCar = "";
            var store = _storeManager.GetStoreByCode(storeCode); // 查找门店

            // 获取城市的推荐车组
            var city = _cityManager.GetCity(store.CityCode, store.RegionCode);
            recommendCar = city?.RecommendCar;

            // 如果城市中没有取到，则获取国家的推荐车组
            if (string.IsNullOrWhiteSpace(recommendCar))
            {
                var region = _regionManager.GetRegion(store.RegionCode);
                var country = _countryManager.GetCountry(region.CountryCode, region.CountryName);//国家信息
                recommendCar = country?.RecommendCar;
            }

            return (recommendCar ?? "")
                .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
        }

        /// <summary>
        /// 设置车组增值服务的中文名称，如果没有对应的中文名称，则排除之。
        /// </summary>
        /// <param name="carGroup"></param>
        private void SetCarEquipments(CarGroup carGroup)
        {
            var list = new List<CarEquipment>();
            foreach (var dto in carGroup.CarEquipments)
            {
                var content = _contentManager.GetContentEquipments(dto.Type);
                if (content != null)
                {
                    var equip = new CarEquipment();
                    list.Add(equip);

                    // 赋值
                    equip.Type = dto.Type;
                    equip.Amount = dto.Amount;
                    equip.Quantity = dto.Quantity;
                    equip.UnitName = dto.UnitName;
                    equip.UnitPrice = dto.UnitPrice;
                    equip.CurrencyCode = dto.CurrencyCode;
                    equip.Name = content.Field1;
                    if (content.Field31.HasValue && content.Field31.Value == true)
                    {
                        equip.IsCanBuyMore = true;
                    }
                }
            }

            carGroup.CarEquipments = list.OrderBy(e => e.IsCanBuyMore).ToList();
        }

        /// <summary>
        /// 读取数据库的车辆信息来更新车辆信息
        /// </summary>
        /// <param name="carGroup"></param>
        /// <param name="regionCode"></param>
        private void SetFleetInfo(CarGroup carGroup, string regionCode)
        {
            var region = _regionManager.GetRegion(regionCode);
            var fleet = _fleetManager.GetORFleet(region, carGroup);
            if (fleet != null)
            {
                carGroup.PictureURL = GetPictureURL(carGroup, fleet);
            }
        }

        /// <summary>
        /// 获取车辆的图片
        /// </summary>
        /// <param name="carGroup"></param>
        /// <returns></returns>
        private string GetPictureURL(CarGroup carGroup, ORFleet fleet)
        {
            string pictureURL = carGroup.PictureURL;

            // 1. 读取数据库的车辆图片，因为查询订单时，如果订单不是在我们官网下的，可能为空。
            if (string.IsNullOrWhiteSpace(pictureURL))
            {
                pictureURL = fleet.ImgMedium;
            }

            // 2. 处理图片路径目录
            if (!string.IsNullOrWhiteSpace(pictureURL)
                && !(pictureURL.Contains("/Content/images/") || pictureURL.Contains("http")))
            {
                pictureURL = string.Format(SiteConfig.AvisVehicleImgUrl, pictureURL);
            }

            return pictureURL;
        }

        /// <summary>
        /// 获取所有价格包含（PriceInclude）的简写中文解释
        /// </summary>
        /// <param name="carGroup">车组信息</param>
        /// <returns></returns>
        private List<string> GetSimplePriceInclude(CarGroup carGroup)
        {
            // 获取所有价格包含（PriceInclude）的简写中文解释
            // 注意：+号表示一条内容里面同时包含关键字，有 +号 需要排在前面
            var dic = _wizardManager.GetSimplePriceIncludeTranslations();

            var list = new List<string>();
            foreach (var coverage in carGroup.PriceInclue.Coverages)
            {
                var existKey = dic.Keys.FirstOrDefault(k =>
                {
                    // 判断保险内容里是否同时包含关键字
                    var keys = k.Split("+".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    foreach (var key in keys)
                    {
                        if (!coverage.Content.Contains(key))
                        {
                            return false;
                        }
                    }

                    return true;
                });

                if (!string.IsNullOrEmpty(existKey))
                {
                    list.Add(dic[existKey]);
                }
            }

            return list;
        }

        /// <summary>
        /// 获取套餐价格包含的中文详细内容（行驶限制、保险项目、费用）
        /// </summary>
        /// <param name="carGroup">车组信息</param>
        /// <returns></returns>
        private List<string> GetPriceInclude(CarGroup carGroup)
        {
            // 获取所有价格包含（PriceInclude）的中文解释
            var dicCache = _wizardManager.GetPriceIncludeTranslations();

            var list = new List<string>();
            foreach (var coverage in carGroup.PriceInclue.Coverages)
            {
                if (dicCache.ContainsKey(coverage.Content))
                {
                    list.Add(dicCache[coverage.Content]);
                }
                else
                {
                    list.Add(coverage.Content);
                }
            }

            if (carGroup.PriceInclue.Distance.Unlimited)
            {
                list.Add(dicCache["Unlimited Mileage/kilometers"]);
            }
            else
            {
                list.Add($"里程限制：{carGroup.PriceInclue.Distance.Quantity}{carGroup.PriceInclue.Distance.DistanceUnit} {carGroup.PriceInclue.Distance.PeriodUnit}");
            }

            foreach (var charge in carGroup.PriceInclue.VehicleCharges)
            {
                if (charge.Contains("Local Tax"))
                {
                    list.Add($"{dicCache["Tax"]}|{dicCache["Location surcharge"]}");
                    continue;
                }
                else if (charge.Contains("One way fee"))
                {
                    list.Add(charge);
                    continue;
                }

                if (dicCache.ContainsKey(charge))
                {
                    list.Add(dicCache[charge]);
                }
                else
                {
                    list.Add(charge);
                }
            }

            return list;
        }
        #endregion
    }
}
